package com.concandthreads;

/**
 * Created by nkrivko on 08.12.2014.
 */
public class DeadLockHolder {

    private final Object one = new Object();
    private final Object two = new Object();
    private final Object tie = new Object();


    public void doDeadlock() {
        Runnable target = new Runnable() {
            @Override
            public void run() {
                try {
                    doSomething();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };
        Runnable target1 = new Runnable() {
            @Override
            public void run() {
                try {
                    doSomethingElse();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Runnable tieRun = new Runnable() {
            @Override
            public void run() {
                doSomethingElseElse();

            }
        };
        for (int i = 0; i < 10; i++) {
            new Thread(target).start();
            new Thread(target1).start();
            new Thread(tieRun).start();
        }
    }

    private void doSomethingElse() throws InterruptedException {
        int oneHash = System.identityHashCode(one);//revoke bias
        int twoHash = System.identityHashCode(two);
//        int oneHash = one.hashCode();
//        int twoHash = two.hashCode();
        if (oneHash<twoHash) {
            synchronized (one) {
                synchronized (two) {
                    System.out.println("inside two");
                }
            }
        }
    }

    private void doSomething() throws InterruptedException {
        int oneHash = System.identityHashCode(one);
        int twoHash = System.identityHashCode(two);
//        int oneHash = one.hashCode();
//        int twoHash = two.hashCode();
        if (oneHash>twoHash) {
            synchronized (two) {
                synchronized (one) {
                    System.out.println("inside one");
                }
            }
        }
    }

    public void doSomethingElseElse(){
        int oneHash = System.identityHashCode(one);
        int twoHash = System.identityHashCode(two);
//        int oneHash = one.hashCode();
//        int twoHash = two.hashCode();
        if(oneHash==twoHash)
        synchronized (tie){
            synchronized (one) {
                synchronized (two) {
                    System.out.println("inside tie");
                }
            }
        }
    }
}
